package chapter_19


trait Queue2[T] {
  def head: T
  def tail: Queue2[T]
  def append(x: T): Queue2[T]
}


object Queue2 {
  def apply[T](xs: T*): Queue2[T] =
    new QueueTmpl[T](xs.toList, Nil)

  // 私有类
  private class QueueTmpl[T] (
    private val leading: List[T],
    private val trailing: List[T]
                             ) extends Queue2[T] {
    def mirror =
      if (leading.isEmpty)
        new QueueTmpl(trailing.reverse, Nil)
      else
        this

    def head: T = mirror.leading.head

    def tail: QueueTmpl[T] = {
      val q = mirror
      new QueueTmpl(q.leading.tail, q.trailing)
    }

    def append(x: T) =
      new QueueTmpl(leading, x :: trailing)

    override def toString = {
      "leading: " + leading.mkString(" ") + "\n" +
        "trailing: " + trailing.mkString(" ") + "\n"
    }
  }
  /*
  代码中定义了特质Queue，声明了方法head、tail和append。这三个方法都实现了子类
  QueueTmpl中，而它本身是对象Queue的内部类。这个方案暴露给客户的信息与前面相同，
  但使用了不同的技术。代之以逐个隐藏构造器的方法，这个版本隐藏全体实现类。
   */
}


object Queue2App {
  def main(args: Array[String]): Unit = {
    val q  = Queue2.apply(1, 2, 3)
    println(q)
    q.append(10)
    println(q)
  }
}